package net.bgraham.collectionbatcher;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import junit.framework.TestCase;

import net.bgraham.collectionbatcher.ArrayListBatcher;
import net.bgraham.collectionbatcher.ConflatingBatcher;
import net.bgraham.collectionbatcher.IBatchListener;
import net.bgraham.collectionbatcher.Log;
import net.bgraham.collectionbatcher.Util;

import org.junit.Test;

public class BatcherFunctionalTest  extends TestCase
{
	private static long maxTimeToWaitBetweenBatches = 900;
	private static long maxTimeToWaitBetweenUpdates = 100;
	
	static long count = 0;
	
	@Test
	public static void testBatcherWithIntegers()
	{
		count = 0;
		ArrayListBatcher<Integer> batcher = new ArrayListBatcher<Integer>(
				new IBatchListener<Integer>()
				{
					public void batchCollected(Collection<Integer> batch, boolean fullTimeoutHit)
					{
						Log.log(++count + ") batchCollected(" + fullTimeoutHit + ") : " + batch.toString());
					}
				},
				maxTimeToWaitBetweenBatches, maxTimeToWaitBetweenUpdates
				);
		//testBatcher(batcher);
		
		Log.log("start");
		int x = 0;
		while (x < 1000)
		{
			batcher.add(x++);
			x++;
			if (x % 50 == 0)
			{
				Util.doSleep(new Integer((int)(Math.random() * 150)));
			}
		}
		
		// pause to let batcher shut down
		Log.log("shutting down");
		Util.doSleep(1000);
		batcher.exit();
		Log.log("done");
	}
	
	@Test
	public static void testConflatingBatcherWithIntegers()
	{
		count = 0;
		
		ConflatingBatcher<Integer> batcher = new ConflatingBatcher<Integer>(
				new IBatchListener<Integer>()
				{
					public void batchCollected(Collection<Integer> batch, boolean fullTimeoutHit)
					{
						ArrayList<Integer> list = new ArrayList<Integer>(batch);
						Collections.sort(list);
						Log.log(++count + ") batchCollected(" + fullTimeoutHit + ") : " + list.toString());
					}
				},
				maxTimeToWaitBetweenBatches, maxTimeToWaitBetweenUpdates
				);
		
		Log.log("start");
		int x = 0;
		while (x < 1000)
		{
			batcher.add(new Integer((int)(Math.random() * 50)));
			x++;
			if (x % 50 == 0)
			{
				Util.doSleep(new Integer((int)(Math.random() * 150)));
			}
		}
		
		// pause to let batcher shut down
		Log.log("shutting down");
		Util.doSleep(1000);
		batcher.exit();
		Log.log("done");
	}
	
	@Test
	public static void testBatcherWithStrings()
	{
		count = 0;
		
		ArrayListBatcher<String> batcher = new ArrayListBatcher<String>(
				new IBatchListener<String>()
				{
					public void batchCollected(Collection<String> batch, boolean fullTimeoutHit)
					{
						Log.log(++count + ") batchCollected(" + fullTimeoutHit + ") : " + batch.toString());
					}
				},
				maxTimeToWaitBetweenBatches, maxTimeToWaitBetweenUpdates
				);
		
		Log.log("start");
		int x = 0;
		while (x < 1000)
		{
			byte[] yep = new byte[1];
			yep[0] = (byte)('A' + (long)(Math.random() * 26));
			batcher.add(new String(yep));
			x++;
			if (x % 50 == 0)
			{
				Util.doSleep((long)(Math.random() * 150));
			}
		}
		
		// pause to let batcher shut down
		Log.log("shutting down");
		Util.doSleep(1000);
		batcher.exit();
		Log.log("done");
	}
	
	@Test
	public static void testConflatingBatcherWithStrings()
	{
		count = 0;
		
		ConflatingBatcher<String> batcher = new ConflatingBatcher<String>(
				new IBatchListener<String>()
				{
					public void batchCollected(Collection<String> batch, boolean fullTimeoutHit)
					{
						ArrayList<String> list = new ArrayList<String>(batch);
						Collections.sort(list);
						Log.log(++count + ") batchCollected(" + fullTimeoutHit + ") : " + list.toString());
					}
				},
				maxTimeToWaitBetweenBatches, maxTimeToWaitBetweenUpdates
				);
		
		Log.log("start");
		int x = 0;
		while (x < 1000)
		{
			byte[] yep = new byte[1];
			yep[0] = (byte)('A' + (long)(Math.random() * 26));
			batcher.add(new String(yep));
			x++;
			if (x % 50 == 0)
			{
				Util.doSleep((long)(Math.random() * 150));
			}
		}
		
		// pause to let batcher shut down
		Log.log("shutting down");
		Util.doSleep(1000);
		batcher.exit();
		Log.log("done");
	}
}
